package com.fh.modules.ems.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fh.common.exception.Assert;
import com.fh.common.util.DateUtils;
import com.fh.common.web.impl.AbstractServiceImpl;
import com.fh.modules.ems.entity.EmsCoupon;
import com.fh.modules.ems.entity.EmsCouponTemplate;
import com.fh.modules.ems.mapper.EmsCouponMapper;
import com.fh.modules.ems.model.CouponModel;
import com.fh.modules.ems.service.IEmsCouponService;
import com.fh.modules.ems.service.IEmsCouponTemplateProductCategoryRelService;
import com.fh.modules.ems.service.IEmsCouponTemplateProductRelService;
import com.fh.modules.ems.service.IEmsCouponTemplateService;
import com.fh.modules.oms.entity.OmsOrderWechat;
import com.fh.modules.pms.entity.PmsProduct;
import com.fhMall.request.AddMemberCouponRequest;
import com.fhMall.request.QueryMemberCouponRequest;
import com.fhMall.request.SaveMemberCouponRequest;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description: 优惠券
 * @author： code generator
 * @date： 2019-09-26
 * @version： V1.0
 */
@Service
public class EmsCouponServiceImpl extends AbstractServiceImpl<EmsCouponMapper, EmsCoupon> implements IEmsCouponService {

    @Autowired
    private IEmsCouponTemplateService emsCouponTemplateService;
    @Autowired
    private IEmsCouponTemplateProductRelService emsCouponTemplateProductRelService;
    @Autowired
    private IEmsCouponTemplateProductCategoryRelService emsCouponTemplateProductCategoryRelService;

    @Autowired
    private EmsCouponMapper emsCouponMapper;

    @Override
    public boolean validateCouponUseable(PmsProduct pmsProduct, Integer productCounts, BigDecimal totalPrice, Serializable couponId) {
        EmsCoupon emsCoupon=this.getById(couponId);
        return this.validateCouponUseable(pmsProduct,productCounts,totalPrice,emsCoupon);
    }

    @Override
    public boolean validateCouponUseable(PmsProduct pmsProduct, Integer productCounts, BigDecimal totalPrice, EmsCoupon emsCoupon) {
        EmsCouponTemplate emsCouponTemplate=emsCouponTemplateService.getById(emsCoupon.getCouponTemplateId());
        /**使用类型：0->全场通用；1->指定分类；2->指定商品*/
        int useType=emsCouponTemplate.getUseType();
        if(useType==0){
            return totalPrice.compareTo(emsCouponTemplate.getPrice())>=0;
        }else if(useType==1){
            if(emsCouponTemplateProductCategoryRelService.validateProductCategoryCouponTemplateRel(pmsProduct.getProductCategoryId(),emsCouponTemplate.getId())){
                return pmsProduct.getPrice().multiply(new BigDecimal(productCounts)).compareTo(emsCouponTemplate.getPrice())>=0;
            }
        }else if(useType==2){
            if(emsCouponTemplateProductRelService.validateProductCouponTemplateRel(pmsProduct.getId(),emsCouponTemplate.getId())){
                return pmsProduct.getPrice().multiply(new BigDecimal(productCounts)).compareTo(emsCouponTemplate.getPrice())>=0;
            }
        }
        return false;
    }


    @Override
    public void useCoupon(OmsOrderWechat omsOrderWechat) {
        Integer couponId = omsOrderWechat.getCouponId();
        if (couponId != null) {
            EmsCoupon emsCoupon = super.getById(couponId);
            //验证订单优惠卷
            validOrderCoupon(omsOrderWechat, emsCoupon);
            emsCoupon.setOrderId(omsOrderWechat.getId());
            emsCoupon.setUseStatus(1);
            emsCoupon.setUseTime(new Date());
            super.updateById(emsCoupon);
        }
    }

    @Override
    public void returnCoupon(Serializable id) {
        EmsCoupon emsCoupon = super.getById(id);
        if (emsCoupon != null) {
            Date overdueTime = emsCoupon.getOverdueTime();
            if (overdueTime != null && System.currentTimeMillis() > overdueTime.getTime()) {
                //过期了
                emsCoupon.setUseStatus(2);
            } else {
                emsCoupon.setUseStatus(0);
            }
            super.updateById(emsCoupon);
        }
    }

    @Override
    public void memberGetCoupon(SaveMemberCouponRequest saveMemberCouponRequest) {
        //1、新增EmsCoupon优惠券,getType0：被动领取；1：主动领取
        EmsCouponTemplate emsCouponTemplate = emsCouponTemplateService.getById(saveMemberCouponRequest.getTemplateId());
        int haveGetTimes=this.userHaveGetCouponTimes(saveMemberCouponRequest.getMemberId(),saveMemberCouponRequest.getTemplateId());
        Assert.isTrue(emsCouponTemplate.getPerLimit()<=haveGetTimes,"您已经领取过了");
        this.saveCoupon(saveMemberCouponRequest.getMemberId(), emsCouponTemplate, 1);
        //2、增加优惠券模板已领取数量,并对是否能领取进行了验证
        emsCouponTemplateService.addCouponTemplateReciveCount(emsCouponTemplate);
    }

    @Override
    public int userHaveGetCouponTimes(Integer memberId,Integer couponTemplateId) {
        LambdaQueryWrapper<EmsCoupon> query=new LambdaQueryWrapper<>();
        query.eq(EmsCoupon::getMemberId,memberId);
        query.ge(EmsCoupon::getCouponTemplateId,couponTemplateId);
        return this.count(query);
    }

    @Override
    public List<CouponModel> queryMemberCoupon(QueryMemberCouponRequest queryMemberCouponRequest) {
        PageHelper.startPage(queryMemberCouponRequest.getPageNo(), queryMemberCouponRequest.getPageSize(), false);
        return emsCouponMapper.queryMemberCoupon(queryMemberCouponRequest);
    }

    @Override
    public Integer queryAvailableCouponCount(Integer memberId) {
        LambdaQueryWrapper<EmsCoupon> query=new LambdaQueryWrapper<>();
        query.eq(EmsCoupon::getDelFlag,0);
        query.eq(EmsCoupon::getUseStatus,0);
        query.eq(EmsCoupon::getMemberId,memberId);
        query.ge(EmsCoupon::getOverdueTime,new Date());
        return this.count(query);
    }

    /**
     * 验证订单优惠卷
     *
     * @param omsOrderWechat
     * @param emsCoupon
     */
    private void validOrderCoupon(OmsOrderWechat omsOrderWechat, EmsCoupon emsCoupon) {
        if (emsCoupon != null) {
            Assert.isFalse(omsOrderWechat.getMemberId().intValue() == emsCoupon.getMemberId().intValue(), "优惠券无效");
            Assert.isTrue(emsCoupon.getDelFlag() == 1 || emsCoupon.getUseStatus() != 0, "优惠券无效");
            EmsCouponTemplate emsCouponTemplate = emsCouponTemplateService.getById(emsCoupon.getCouponTemplateId());
            Assert.isFalse(emsCouponTemplate.getPrice().compareTo(omsOrderWechat.getCouponPrice()) == 0, "优惠券价格有异");
        }
    }

    /**
     * 新增EmsCoupon优惠券
     * @param memberId
     * @param emsCouponTemplate
     * @param getType 0 被动领取；1：主动领取
     * @return
     */
    private EmsCoupon saveCoupon(Serializable memberId, EmsCouponTemplate emsCouponTemplate, int getType) {
        EmsCoupon emsCoupon = new EmsCoupon();
        emsCoupon.setGetType(getType);
        emsCoupon.setCouponTemplateId(emsCouponTemplate.getId());
        emsCoupon.setMemberId((Integer) memberId);
        //设置过期时间
        emsCoupon.setOverdueTime(DateUtils.getCurrentPlusDate(emsCouponTemplate.getOverdueCount()));
        super.save(emsCoupon);
        return emsCoupon;
    }

    /**
     *  用户注册赠送，默认优惠券
     * @return
     */
    public void addMemberCoupon(AddMemberCouponRequest addMemberCouponRequest){
        Date date = new Date();
        List<EmsCouponTemplate> emsCouponTemplates = emsCouponTemplateService.queryTemplateAllByType(addMemberCouponRequest.getCouponTemplatType());
        List<EmsCoupon> emsCoupons = emsCouponTemplates.stream().map(emsCouponTemplate -> {
            //添加领取数量
            emsCouponTemplateService.addCouponTemplateReciveCount(emsCouponTemplate.getId());

            return EmsCoupon.builder()
                    .memberId(addMemberCouponRequest.getMemberId())
                    .couponTemplateId(emsCouponTemplate.getId())
                    .getType(0)
                    .useStatus(0)
                    .overdueTime(emsCouponTemplate.getUseEndTime())
                    .delFlag(0)
                    .createTime(date)
                    .updateTime(date)
                    .build();
        }).collect(Collectors.toList());
        super.saveBatch(emsCoupons);
    }

}
